package hc.server;

import hc.App;
import hc.core.ConditionWatcher;
import hc.core.ContextManager;
import hc.core.EventCenter;
import hc.core.IConstant;
import hc.core.IContext;
import hc.core.IEventHCListener;
import hc.core.IWatcher;
import hc.core.Message;
import hc.core.MsgBuilder;
import hc.core.RootServerConnector;
import hc.core.sip.SIPManager;
import hc.core.util.CUtil;
import hc.core.util.HCURLUtil;
import hc.core.util.IHCURLAction;
import hc.core.util.LogManager;
import hc.server.ui.JcipManager;
import hc.server.ui.SingleMessageNotify;
import hc.server.util.ServerCUtil;
import hc.util.TokenManager;

public class ServerInitor {
	public static void doNothing(){
		
	}
	
	final static IWatcher LINE_OFF_BIZ = new IWatcher(){
		boolean isClientReq;
		public void setPara(Object p) {
			isClientReq = (Boolean)p;
		}

		public boolean watch() {
			ContextManager.setStatus(ContextManager.STATUS_NEED_NAT);
			
			//如果不调用此步,可能导致Root提供给手机客户端以错误的状态信息.
			RootServerConnector.delLineInfo(TokenManager.getToken(), false);
			
			CUtil.resetCheck();
			
			KeepaliveManager.keepalive.setEnable(false);
			KeepaliveManager.keepalive.setIntervalMS(KeepaliveManager.KEEPALIVE_MS);
			KeepaliveManager.ConnBuilderWatcher.setEnable(false);
			
			if(KeepaliveManager.dServer != null){
				//因为Relay模式，可能为null
				KeepaliveManager.dServer.closeSessionNotServerSocket();
			}

			ConditionWatcher.cancelAllWatch();
			JcipManager.clearAllTimer();
			SIPManager.getSIPContext().resetNearDeployTime();
			
			if(isClientReq == false || SIPManager.isOnRelay()){
				SIPManager.close();
			}
			try{
				//setClient(null)之前，稍等，以响应当前客户可能存在的包
				Thread.sleep(300);
			}catch (Exception e) {
				
			}
			
			SIPManager.getSIPContext().resender.reset();
			
			KeepaliveManager.keepalive.doNowAsynchronous();
			KeepaliveManager.keepalive.setEnable(true);

			return true;
		}

		@Override
		public void cancel() {
		}

		@Override
		public boolean isNotCancelable() {
			return false;
		}};
		
	static {
		if(IConstant.serverSide){
			EventCenter.addListener(new IEventHCListener(){
				IHCURLAction urlAction;
				public boolean action(final byte[] bs) {
					String cmd = Message.getMsgBody(bs, MsgBuilder.INDEX_MSG_DATA);
//					L.V = L.O ? false : LogManager.log("Receive URL:" + cmd);
					if(urlAction == null){
						urlAction = ContextManager.getContextInstance().getHCURLAction();
					}
					HCURLUtil.process(cmd, urlAction);
					return true;
				}

				public byte getEventTag() {
					return MsgBuilder.E_GOTO_URL;
				}});

			
			EventCenter.addListener(new IEventHCListener(){
				public byte getEventTag(){
					return MsgBuilder.E_LINE_OFF_EXCEPTION;
				}
				
				public boolean action(byte[] bs) {					
					Boolean isClientReq = Boolean.parseBoolean(Message.getMsgBody(bs, MsgBuilder.INDEX_MSG_DATA));

					LINE_OFF_BIZ.setPara(isClientReq);
					ConditionWatcher.addWatcher(LINE_OFF_BIZ);
						
					return true;
				}});
			

			EventCenter.addListener(new IEventHCListener(){
				short pwdErrTry;
				long lastErrMS;
				public boolean action(final byte[] bs) {
					hc.core.L.V=hc.core.L.O?false:LogManager.log("Receive the back data which to check CK and password");
					
//					System.out.println("pwdErrTry : " + pwdErrTry + ",  MAXTimers : " + LockManager.MAXTIMES);
					if(pwdErrTry < SystemLockManager.MAXTIMES){
					}else{
						if(System.currentTimeMillis() - lastErrMS < SystemLockManager.LOCK_MS){
							SingleMessageNotify.showOnce(SingleMessageNotify.TYPE_LOCK_CERT, 
									"System is locking now!!!<BR><BR>Err Password or certification more than "+SystemLockManager.MAXTIMES+" times.", 
									"Lock System now!!", 1000 * 60 * 1, App.getSysIcon(App.SYS_WARN_ICON));
							LogManager.errToLog("Err Password or certification more than "+SystemLockManager.MAXTIMES+" times.");
							ContextManager.getContextInstance().send(MsgBuilder.E_AFTER_CERT_STATUS, String.valueOf(IContext.BIZ_SERVER_AFTER_UNKNOW_STATUS));
							SIPManager.notifyRelineon(true);
							
							return true;
						}else{
							resetErrInfo();
						}
					}

					//并将该随机数发送给客户机，客户机用同法处理后回转给服务器
					//服务器据此判断客户机的CertKey和密码状态
					
					if(CUtil.SERVER_READY_TO_CHECK == null){
						hc.core.L.V=hc.core.L.O?false:LogManager.log("Server Reconnected, Skip the back data");
						return true;
					}
					
					byte[] oldbs = CUtil.SERVER_READY_TO_CHECK;
					
					short b = ServerCUtil.checkCertKeyAndPwd(bs, MsgBuilder.INDEX_MSG_DATA, 
							IConstant.passwordBS, CUtil.CertKey, oldbs);
					if(b == IContext.BIZ_SERVER_AFTER_PWD_ERROR){
						ContextManager.getContextInstance().doExtBiz(b, null);
						lastErrMS = System.currentTimeMillis();
						hc.core.L.V=hc.core.L.O?false:LogManager.log("Error Pwd OR Certifcation try "+ (++pwdErrTry) +" time(s)");
					}else if(b == IContext.BIZ_SERVER_AFTER_CERTKEY_ERROR && CUtil.isSecondCertKeyError == true){
						lastErrMS = System.currentTimeMillis();
						
						hc.core.L.V=hc.core.L.O?false:LogManager.log("Error Pwd OR Certifcation try "+ (++pwdErrTry) +" time(s)");

						ContextManager.getContextInstance().send(MsgBuilder.E_AFTER_CERT_STATUS, String.valueOf(IContext.BIZ_SERVER_AFTER_PWD_ERROR));
						hc.core.L.V=hc.core.L.O?false:LogManager.log("Second Cert Key Error, send Err Password status");						
						SIPManager.notifyRelineon(true);
					}else{
						ContextManager.getContextInstance().doExtBiz(b, null);
						
						if(b == IContext.BIZ_SERVER_AFTER_CERTKEY_ERROR && CUtil.isSecondCertKeyError == false){
							hc.core.L.V=hc.core.L.O?false:LogManager.log("Error Pwd OR Certifcation try "+ (++pwdErrTry) +" time(s)");
							CUtil.isSecondCertKeyError = true;
						}else{
							CUtil.resetCheck();
							resetErrInfo();
						}
					}
					return true;
				}

				private void resetErrInfo() {
					pwdErrTry = 0;
					lastErrMS = 0;
				}
	
				public byte getEventTag() {
					return MsgBuilder.E_RANDOM_FOR_CHECK_CK_PWD;
				}});
			
			EventCenter.addListener(new IEventHCListener() {
				
				@Override
				public byte getEventTag() {
					return MsgBuilder.E_TAG_SERVER_RELAY_START;
				}
				
				@Override
				public boolean action(byte[] bs) {
					ContextManager.setConnectionModeStatus(ContextManager.MODE_CONNECTION_RELAY);
					
					if(SIPManager.isOnRelay()){
						ContextManager.setStatus(ContextManager.STATUS_READY_MTU);
					}
					return true;
				}
			});
			
		}
	}
}
